/**
 * \file glext.h
 * GL Extensions
 * 
 * Defines pointers to functions of required
 * GL extensions. 
 * \sa 	render.cpp
 **
 * WTF Engine
 * 
 * License... etc.
 */

#ifndef __glextH__
#define __glextH__

#include <GL/gl.h>
#include <GL/glext.h>

/**
 * Function pointers to extensions we require.
 * These are currently initialised by the Renderer (render.cpp).
 **/
extern PFNGLBINDRENDERBUFFEREXTPROC			glBindRenderbufferEXT;
extern PFNGLRENDERBUFFERSTORAGEEXTPROC		glRenderbufferStorageEXT;
extern PFNGLBINDFRAMEBUFFEREXTPROC			glBindFramebufferEXT;
extern PFNGLCHECKFRAMEBUFFERSTATUSEXTPROC	glCheckFramebufferStatusEXT;
extern PFNGLFRAMEBUFFERTEXTURE2DEXTPROC		glFramebufferTexture2DEXT;
extern PFNGLFRAMEBUFFERRENDERBUFFEREXTPROC 	glFramebufferRenderbufferEXT;
extern PFNGLGENERATEMIPMAPEXTPROC			glGenerateMipmapEXT;
extern PFNGLGENRENDERBUFFERSEXTPROC			glGenRenderbuffersEXT;
extern PFNGLGENFRAMEBUFFERSEXTPROC			glGenFramebuffersEXT;
extern PFNGLDELETERENDERBUFFERSEXTPROC		glDeleteRenderbuffersEXT;
extern PFNGLDELETEFRAMEBUFFERSEXTPROC		glDeleteFramebuffersEXT;

// VBO Related
extern PFNGLGENBUFFERSARBPROC			glGenBuffersARB;
extern PFNGLBINDBUFFERARBPROC			glBindBufferARB;
extern PFNGLBUFFERDATAARBPROC			glBufferDataARB;
extern PFNGLDELETEBUFFERSARBPROC		glDeleteBuffersARB;

// GLSL Related
extern PFNGLCREATESHADEROBJECTARBPROC		glCreateShaderObjectARB;
extern PFNGLSHADERSOURCEARBPROC				glShaderSourceARB;
extern PFNGLCOMPILESHADERARBPROC			glCompileShaderARB;
extern PFNGLGETOBJECTPARAMETERIVARBPROC 	glGetObjectParameterivARB;
extern PFNGLGETINFOLOGARBPROC				glGetInfoLogARB;
extern PFNGLCREATEPROGRAMOBJECTARBPROC		glCreateProgramObjectARB;
extern PFNGLATTACHOBJECTARBPROC				glAttachObjectARB;
extern PFNGLLINKPROGRAMARBPROC				glLinkProgramARB;
extern PFNGLUSEPROGRAMOBJECTARBPROC			glUseProgramObjectARB;
extern PFNGLGETUNIFORMLOCATIONARBPROC		glGetUniformLocationARB;
extern PFNGLGETATTRIBLOCATIONARBPROC		glGetAttribLocationARB;
extern PFNGLUNIFORM2FARBPROC				glUniform2fARB;
extern PFNGLUNIFORM3FARBPROC				glUniform3fARB;
extern PFNGLUNIFORM1IARBPROC				glUniform1iARB;
extern PFNGLVERTEXATTRIBPOINTERARBPROC		glVertexAttribPointerARB;
extern PFNGLENABLEVERTEXATTRIBARRAYARBPROC 	glEnableVertexAttribArrayARB;
extern PFNGLDISABLEVERTEXATTRIBARRAYARBPROC	glDisableVertexAttribArrayARB;

#ifndef __GNUC__
extern PFNGLCLIENTACTIVETEXTUREPROC			glClientActiveTexture;
extern PFNGLACTIVETEXTUREARBPROC			glActiveTextureARB;
#endif

// Cube mapping
#ifndef GL_EXT_texture_cube_map
/* EXT_texture_cube_map */
#define GL_EXT_texture_cube_map             1
#define GL_NORMAL_MAP_EXT                   0x8511
#define GL_REFLECTION_MAP_EXT               0x8512
#define GL_TEXTURE_CUBE_MAP_EXT             0x8513
#define GL_TEXTURE_BINDING_CUBE_MAP_EXT     0x8514
#define GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT  0x8515
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT  0x8516
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT  0x8517
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT  0x8518
#define GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT  0x8519
#define GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT  0x851A
#define GL_PROXY_TEXTURE_CUBE_MAP_EXT       0x851B
#define GL_MAX_CUBE_MAP_TEXTURE_SIZE_EXT    0x851C
#endif

static void checkGLError(const char *label) {
    GLenum errCode;
    const GLubyte *errStr;
    if ((errCode = glGetError()) != GL_NO_ERROR) {
        errStr = gluErrorString(errCode);
		std::cerr << "OOpenGL ERROR: " << errStr << " when " << label;
        throw "OpenGL Error";
	}
}

#endif
